package com.runrunfast.fxj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.runrunfast.fxj.entity.SysResources;
import com.runrunfast.fxj.entity.SysUser;
import com.runrunfast.fxj.exception.FxjException;
import com.runrunfast.fxj.form.SysResourcesForm;
import com.runrunfast.fxj.form.SysResourcesUpdateForm;
import com.runrunfast.fxj.mapper.SysResourcesMapper;
import com.runrunfast.fxj.service.ISysResourcesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.runrunfast.fxj.utils.LevelUtil;
import com.runrunfast.fxj.vo.SysResourcesTreeVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;


import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 权限表 服务实现类
 * </p>
 *
 * @author 陈胤训
 * @since 2019-03-12
 */
@Service
public class SysResourcesServiceImpl extends ServiceImpl<SysResourcesMapper, SysResources> implements ISysResourcesService {

    @Override
    public List<SysResources> listByUserId(Integer userId) {
        return baseMapper.listByUserId(userId);
    }

    @Override
    public List<SysResourcesTreeVo> tree() {
        List<SysResources> sysResources = baseMapper.selectList(null);
        List<SysResourcesTreeVo> vos = Lists.newArrayList();
        sysResources.stream().map(r -> {
            SysResourcesTreeVo treeVo = new SysResourcesTreeVo();
            BeanUtils.copyProperties(r, treeVo);
            vos.add(treeVo);
            return null;
        }).collect(Collectors.toList());
        return sysResourcesTreeVoToTree(vos);
    }



    private List<SysResourcesTreeVo> sysResourcesTreeVoToTree(List<SysResourcesTreeVo> vos) {
        if (CollectionUtils.isEmpty(vos)){
            return Lists.newArrayList();
        }
        /** level -> [dept1:dept2:.....]  */
        Multimap<String,SysResourcesTreeVo> multimap = ArrayListMultimap.create();
        List<SysResourcesTreeVo> treeList = new ArrayList<>();
        for (SysResourcesTreeVo treeVo :vos) {
            multimap.put(treeVo.getPermissions(),treeVo);
            if (LevelUtil.ROOT.equals(treeVo.getPermissions())){
                treeList.add(treeVo);
            }
        }
        /** 按照seq从小到大排序  */
        Collections.sort(treeList, new Comparator<SysResourcesTreeVo>() {
            @Override
            public int compare(SysResourcesTreeVo o1, SysResourcesTreeVo o2) {
                return o1.getSort() - o2.getSort();
            }
        });
        /** 递归生成树  */
        transformResourcesTree(treeList,LevelUtil.ROOT,multimap);
        return treeList;

    }

    /** level : 0 ,0 ,all 0 ->0.1,0.2
     *  level : 0.1
     *  level : 0.2
     * */
    private void transformResourcesTree(List<SysResourcesTreeVo> treeList, String root, Multimap<String,SysResourcesTreeVo> multimap) {
        for (int i = 0; i < treeList.size(); i++) {
            /** 遍历该层的每个元素  */
            SysResourcesTreeVo treeVo = treeList.get(i);
            /** 处理当前层级的数据  */
            String nextlevel = LevelUtil.calculateLevel(root, treeVo.getPermission());
            /** 处理下一层  */
            List<SysResourcesTreeVo> sysResourcesTreeVos = (List<SysResourcesTreeVo>) multimap.get(nextlevel);
            if (!CollectionUtils.isEmpty(sysResourcesTreeVos)){
                /** 按照seq从小到大排序  */
                Collections.sort(sysResourcesTreeVos, new Comparator<SysResourcesTreeVo>() {
                    @Override
                    public int compare(SysResourcesTreeVo o1, SysResourcesTreeVo o2) {
                        return o1.getSort() - o2.getSort();
                    }
                });
                /** 设置下一层权限   给 resourcesTreeVos  list设置参数 */
                treeVo.setResourcesTreeVos(sysResourcesTreeVos);
                /** 进入下一层处理  */
                transformResourcesTree(sysResourcesTreeVos,nextlevel,multimap);
            }
        }
    }



    @Override
    public void add(SysResourcesForm sysResourcesForm) {
        SysResources sysResources = new SysResources();
        /** 如果父id为零 代表最高层    */
        if (0 == sysResourcesForm.getParentId()){
            sysResources.setParentId(0);
            sysResources.setPermissions("sys");
        }else{
            SysResources parentResources = baseMapper.selectOne(new QueryWrapper<SysResources>().eq("resources_id", sysResourcesForm.getParentId()));
            sysResources.setParentId(parentResources.getResourcesId());
            sysResources.setPermissions(parentResources.getPermissions()+":"+parentResources.getPermission());
        }
        BeanUtils.copyProperties(sysResourcesForm,sysResources);
        sysResources.setExternal(true);
        int insert = baseMapper.insert(sysResources);
        if (insert<=0){
            throw  new FxjException(2,"权限添加失败");
        }
    }

    @Override
    public boolean updateInfo(SysResourcesUpdateForm updateForm) {
        SysResources sysResources = new SysResources();
        BeanUtils.copyProperties(updateForm,sysResources);
        int i = baseMapper.updateById(sysResources);
        return 0 >= i ;
    }

    @Override
    public List<SysResourcesTreeVo> TreeListByRoleId(Integer roleId) {
        /** 当前系统所有权限点  */
        List<SysResourcesTreeVo> treeVos = Lists.newArrayList();
        /** 查询角色对应的权限  */
        Set<Integer> collect = baseMapper.getByroleIdResourcesList(roleId).stream().map(e -> e.getResourcesId()).collect(Collectors.toSet());
        /** 查询所有权限  */
        List<SysResources> sysResources = baseMapper.selectList(null);
        sysResources.stream().map(e ->{
            SysResourcesTreeVo adapt = SysResourcesTreeVo.adapt(e);
            if (collect.contains(e.getResourcesId())){
                adapt.setChecked(true);
                }
                treeVos.add(adapt);
                return null;
        }).collect(Collectors.toList());

        return sysResourcesTreeVoToTree(treeVos);
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public void delete(SysResources byId) {
        baseMapper.deleteById(byId.getResourcesId());
        baseMapper.delete(new UpdateWrapper<SysResources>().like("permissions",byId.getPermissions()+":"+byId.getPermission()+"%"));
    }


}
